/**
 *  memset()
 *  nastavi pametovy blok 1 pametovym blokem 2 o <count> bytech
 */
void far *memset(void far *s, int c, unsigned count) {
  char far *xs = (char far *) s;
  while (count--)	*xs++ = c;
  return s;
}

/**
 *  memcpy()
 *  zkopiruje do pameti <dest> pamet <src>, o delce <count>
 */
void far *memcpy(void far *dest, const void far*src, unsigned int count) {
  unsigned char far *ds = (unsigned char far *)dest;
  unsigned char far *ss = (unsigned char far *)src;
  unsigned int i;
    for (i = 0; i < count; i++)
      ds[i] = ss[i];
    return dest;
}

/**
 *  memcmp()
 *  porovna pametovy blok 1 s pametovym blokem 2 o <count> bytech
 */
int memcmp(const void far *cs, const void far *ct, unsigned count) {
  const char far *su1;
  const char far *su2;
  signed char res = 0;
  for( su1 = (char far *)cs, su2 = (char far *)ct; 0 < count; ++su1, ++su2, count--)
    if ((res = *su1 - *su2) != 0)
      break;
  return res;
}

/**
 *  strcat()
 *  zkopiruje string src na konec stringu dest,
 *  spoji string dest a src, vrati v dest...
 */
char far *strcat(char far *dest, const char far *src) {
    char far *r = dest;

    while (*dest != '\0')
        dest++;

    while ((*dest++ = *src++) != '\0')
        continue;

    return r;
}

/**
 *  strcmp()
 *  porovna string d se stringem s
 *  pokud jsou stringy shodne, vrati 0
 */
int strcmp(char far *d, char far *s) {
  while (*s != '\0' && *d != '\0') {
    if (*d == *s)
      ++s, ++d;
    else
      return *d - *s;
  }
  return *d - *s;
}

/**
 *  strcpy()
 *  zkopiruje <src> do <dest> zakonceny '\0'
 */
char far *strcpy(char far *dest, const char far *src) {
char far *tmp = dest;
  while ((*dest++ = *src++) != '\0');
    return tmp;
}

/**
 *  strncpy()
 *  zkopiruje <src> do <dest> o <count> znacich
 */
char far *strncpy(char far *dest, const char far *src, unsigned count) {
char far *tmp = dest;
  while (count-- && (*dest++ = *src++) != '\0');
    return tmp;
}

/**
 *  strlen()
 *  vstup: ukazatel na zacatek stringu zakonceneho '\0'
 *  vystup: delka stringu (pocet znaku pred nulovym bajtem)
 */
int strlen(const char far *str) {
  int i = 0;
    while(*str++) i++;
  return i;
}

/**
 *  strtoupper()
 *  prevede znaky na velka pismena ve stringu <s1> do stringu <s2>
 */
char far *strtoupper(const char far *src, char far *dest) {
  char far *tmp = dest;
  while(*src) {
    *dest = toupper(*src);
    src++; dest++;
  }
  *dest = '\0';
  return tmp;
}

/**
 *  strtolower()
 *  prevede znaky na mala pismena ve stringu <s1> do stringu <s2>
 */
char far *strtolower(const char far *src, char far *dest) {
  char far *tmp = dest;
  while(*src) {
    *dest = tolower(*src);
    src++; dest++;
  }
  *dest = '\0';
  return tmp;
}

/**
 *  strput()
 *  vstup: ukazatel na string, ktery se bude tisknout na vystup
 *  vystup: [void]
 */
void strput(const char far *str) {
  while(*str)
    putchar(*str++);

  return;
}

/**
 *  puts()
 *  vstup: ukazatel na string, ktery se bude tisknout na vystup (prida na konec '\n')
 *  vystup: [void]
 */
void puts(const char far *str) {
  while(*str)
    putchar(*str++);

  putchar('\n');
  return;
}

/**
 *  pos()
 *  urci pozici prvniho znaku <c> ve stringu <s>
 */
int pos(const char far *s, char c) {
  int i = 0;
  while(*s++ != c)
    if(!*s)
      return POS_NOT_FOUND;
    else
      i++;
  return i;
}

/**
 *  l_pos()
 *  urci pozici posledniho znaku <c> ve stringu <s>
 */
int l_pos(const char far *s, char c) {
  int i = 0, pos = POS_NOT_FOUND;
  while(s[i]) {
    if(s[i] == c)
      pos = i;
    i++;
  }
  return pos;
}

/**
 *  gets()
 *  sejme string z klavesnice, kazdy znak vytiskne na STDOUT
 */
char far *gets(char far *cs) {
  return _gets(cs, 0xFFFF);
}

/**
 *  _gets()
 *  sejme string z klavesnice o maximalni delce <size>, kazdy znak vytiskne na STDOUT
 */
char far *_gets(char far *cs, int size) {
  unsigned int counter = 0;
  unsigned char c = '\0';
  char far *s;

  s = cs;
  while(1) {
    if(counter >= size)
      break;
    c = getchar();
    if(c == '\r') break;
    if(c == '\n') break;
    if(c == '\0') break;
    if(c == '\t') c = ' ';

      if(!(counter == 0 && c == '\b'))
        putchar(c);

      if(c == '\b') {
        if (counter > 0)
        counter--;
      }
      else
        *(s+(counter++)) = c;
  }
  putchar('\n');
  *(s+(counter++)) = '\0';
  return s;
}

/**
 *  far2char()
 *  do pole char * ulozi far char * string
 */
char *far2char(const char far *in, char *out) {
char *tmp = out;
  while ((*out++ = *in++) != '\0');
    return tmp;
}

/**
 *  char2far()
 *  do pole fr char * ulozi char * string
 */
char far *char2far(const char *in, char far *out) {
char far *tmp = out;
  while ((*out++ = *in++) != '\0');
    return tmp;
}
